# Collision Example - Robot walking through a maze
# see if it can be done without setting flags from maya

import direct.directbase.DirectStart
from pandac.PandaModules import *
import random
from direct.task import Task
from direct.showbase import DirectObject

##################

class World(DirectObject.DirectObject):
  def __init__(self):

    light1 = PointLight ('light1')
    lightNode1 = render.attachNewNode (light1)
    lightNode1.setPos(0,-20,50)
    render.setLight(lightNode1)
   
    base.disableMouse()

    self.robot = loader.loadModel('robot')

    self.robot.reparentTo(render)
   
    base.camera.setPos(0,-20,5)
    base.camera.lookAt(self.robot)
   
    # set up keyboard controls
   
    self.goForward=0
    self.goBackwards=0
    self.goRight=0
    self.goLeft=0
   
    self.accept ("arrow_left", self.setGoLeft, [1])
    self.accept ("arrow_left-up", self.setGoLeft, [0])
   
    self.accept ("arrow_right", self.setGoRight, [1])
    self.accept ("arrow_right-up", self.setGoRight, [0])
   
    self.accept ("arrow_up", self.setGoForward, [1])
    self.accept ("arrow_up-up", self.setGoForward, [0])
 
    self.accept ("arrow_down", self.setGoBackwards, [1])
    self.accept ("arrow_down-up", self.setGoBackwards, [0])
 
    # set up update task
    self.prevtime = 0
    taskMgr.add(self.update,"updateTask")
   
    wall1 = loader.loadModel("maze2")
    wall1.reparentTo (render)
    wall1.setPos(0,5,0)  
    wall1.setCollideMask (1)
   
    # collision setup for the robot
   
    cs = CollisionSphere(0, 0, 1, 1)
    cnode = self.robot.attachNewNode(CollisionNode('cnode'))
    cnode.setPos(0,0,0)
    cnode.node().addSolid(cs)
   
    self.traverser = CollisionTraverser('collision traverser')
   
    self.traverser.showCollisions(render)

    self.pusher = CollisionHandlerPusher()
    self.pusher.addCollider(cnode,self.robot)
    self.traverser.addCollider(cnode, self.pusher)

  def setGoLeft (self,value):
    self.goLeft = value
   
  def setGoRight (self,value):
    self.goRight = value
   
  def setGoForward (self,value):
    self.goForward = value
   
  def setGoBackwards (self,value):
    self.goBackwards = value
       
  # update task
 
  def update (self, task):
   
    elapsed = task.time - self.prevtime
   
    if self.goLeft:
      self.robot.setH(self.robot.getH() + elapsed * 300)
    if self.goRight:
      self.robot.setH(self.robot.getH() - elapsed * 300)

    # this code moves the avatar forward.
    # "forward" usually means "along the Y axis".  however, since the avatar can turn,
    # it really means "along the Y axis relative to the direction I'm facing"
    # you can use the getRelativeVector () function to find out what that is
   
    forwardVec =  VBase3(0,-1,0)
    xformedVec = render.getRelativeVector(self.robot,forwardVec)
   
    oldPos = self.robot.getPos()
    if self.goForward:  
      newPos = oldPos + xformedVec * elapsed * 5
      self.robot.setPos(newPos)
     
    if self.goBackwards:  
      newPos = oldPos - xformedVec * elapsed * 5
      self.robot.setPos(newPos)  
     
    # do collisions
   
    self.traverser.traverse(render)
     
    self.prevtime = task.time
    return Task.cont
   
w=World()
run()
